import 'dart:convert';

import 'package:shared_preferences/shared_preferences.dart';

import '../model/User.dart';
import '../service/HttpService.dart';

// 缓存
class Storage {
  // 单利模式
  static final Storage _instance = Storage._internal();

  factory Storage() => _instance;
  late final SharedPreferences _prefs;

  Storage._internal();

  static final String ACCESS_TOKEN = "access_token";
  static final String REFRESH_TOKEN = "refresh_token";

  Future<void> init() async => _prefs = await SharedPreferences.getInstance();

  Future<bool> setJson(String key, Object value) async => await _prefs.setString(key, jsonEncode(value));

  Future<bool> setString(String key, String value) async => await _prefs.setString(key, value);

  String getString(String key) => _prefs.getString(key) ?? "";

  Future<bool> setBool(String key, bool value) async => await _prefs.setBool(key, value);

  bool getBool(String key) => _prefs.getBool(key) ?? false;

  Future<bool> setList(String key, List<String> value) async => await _prefs.setStringList(key, value);

  List<String> getList(String key) => _prefs.getStringList(key) ?? [];

  Future<void> remove(String key) async => _prefs.remove(key);

  Future<void> saveTokens(String accessToken, String refreshToken) async {
    await setString(ACCESS_TOKEN, accessToken);
    await setString(REFRESH_TOKEN, refreshToken);
  }

  Future<bool> setAccessToken(String value) async => await _prefs.setString(ACCESS_TOKEN, value);

  String getAccessToken() => _prefs.getString(ACCESS_TOKEN) ?? "";

  Future<bool> setRefreshToken(String value) async => await _prefs.setString(REFRESH_TOKEN, value);

  String getRefreshToken() => _prefs.getString(REFRESH_TOKEN) ?? "";

  Future<void> removeToken() async {
    remove(ACCESS_TOKEN);
    remove(REFRESH_TOKEN);
  }

  /// 获取用户
  Future<UserModel?> getUser() async {
    String? userStr = getString("user");
    if (userStr.isEmpty) return null;

    try {
      Map<String, dynamic> userMap = jsonDecode(userStr);
      return UserModel.fromJson(userMap);
    } catch (e) {
      return null;
    }
  }
}
